#include "preHeader.h"
#include "Session/GameSession.h"
#include "Session/GameSessionHandler.h"
#include "SQLHelper.h"

int GameSessionHandler::HandleLoadAllSocialFriend(GameSession *pSession, INetPacket &pck, const RPCActor::RequestMetaInfo &info)
{
	auto LoadAllSocialFriend = [GSRPCAsyncTaskArgs]() {
		TNetBuffer<65536> buffer;
		size_t n = 0;
		auto connPtr = sMysqlDatabasePool.GetCharDB()->GetConnAutoPtr();
		if (connPtr) {
			uint32 lastInstID[2]{};
			auto sqlFormat = CreateSQL4SelectEntity<social_friend>(
				"characterId>%u OR (characterId=%u AND friendId>%u) ORDER BY characterId,friendId");
mark:		auto rst = connPtr->FastQueryFormat(
				sqlFormat.c_str(), lastInstID[0], lastInstID[0], lastInstID[1]);
			if (rst) {
				while (rst.NextRow()) {
					auto row = rst.Fetch();
					auto instInfo = LoadEntityFromMysqlRow<social_friend>(row);
					SaveToINetStream(instInfo, buffer);
					lastInstID[0] = instInfo.characterId;
					lastInstID[1] = instInfo.friendId;
					if (++n % 2500 == 0) {
						GameSession::Feedback(gsPtr, buffer, info.sn, RPCErrorNone, false);
						buffer.Clear();
					}
				}
				if (connPtr->GetLastErrno() == 0) {
					GameSession::Feedback(gsPtr, buffer, info.sn, RPCErrorNone, true);
				} else {
					goto mark;
				}
			} else {
				GameSession::FeedbackError(gsPtr, info.sn, DBPErrorQueryMysqlFailed);
			}
		} else {
			GameSession::FeedbackError(gsPtr, info.sn, DBPErrorConnectMysqlFailed);
		}
	};
	sDeferAsyncTaskMgr.AddTask(CreateAsyncTask(LoadAllSocialFriend));
	return SessionHandleCapture;
}

int GameSessionHandler::HandleLoadAllSocialIgnore(GameSession *pSession, INetPacket &pck, const RPCActor::RequestMetaInfo &info)
{
	auto LoadAllSocialIgnore = [GSRPCAsyncTaskArgs]() {
		TNetBuffer<65536> buffer;
		size_t n = 0;
		auto connPtr = sMysqlDatabasePool.GetCharDB()->GetConnAutoPtr();
		if (connPtr) {
			uint32 lastInstID[2]{};
			auto sqlFormat = CreateSQL4SelectEntity<social_ignore>(
				"characterId>%u OR (characterId=%u AND ignoreId>%u) ORDER BY characterId,ignoreId");
mark:		auto rst = connPtr->FastQueryFormat(
				sqlFormat.c_str(), lastInstID[0], lastInstID[0], lastInstID[1]);
			if (rst) {
				while (rst.NextRow()) {
					auto row = rst.Fetch();
					auto instInfo = LoadEntityFromMysqlRow<social_ignore>(row);
					SaveToINetStream(instInfo, buffer);
					lastInstID[0] = instInfo.characterId;
					lastInstID[1] = instInfo.ignoreId;
					if (++n % 2500 == 0) {
						GameSession::Feedback(gsPtr, buffer, info.sn, RPCErrorNone, false);
						buffer.Clear();
					}
				}
				if (connPtr->GetLastErrno() == 0) {
					GameSession::Feedback(gsPtr, buffer, info.sn, RPCErrorNone, true);
				} else {
					goto mark;
				}
			} else {
				GameSession::FeedbackError(gsPtr, info.sn, DBPErrorQueryMysqlFailed);
			}
		} else {
			GameSession::FeedbackError(gsPtr, info.sn, DBPErrorConnectMysqlFailed);
		}
	};
	sDeferAsyncTaskMgr.AddTask(CreateAsyncTask(LoadAllSocialIgnore));
	return SessionHandleCapture;
}

int GameSessionHandler::HandleDeleteAllSocialData(GameSession *pSession, INetPacket &pck, const RPCActor::RequestMetaInfo &info)
{
	auto DeleteAllSocialData = [GSRPCAsyncTaskArgs]() {
		NetBuffer buffer;
		uint32 characterId;
		(*pckPtr) >> characterId;
		auto connPtr = sMysqlDatabasePool.GetCharDB()->GetConnAutoPtr();
		if (connPtr) {
			auto rst1 = connPtr->ExecuteFormat(CreateSQL4DeleteEntity<social_friend>
				("characterId=%u OR friendId=%u").c_str(), characterId, characterId);
			auto rst2 = connPtr->ExecuteFormat(CreateSQL4DeleteEntity<social_ignore>
				("characterId=%u OR ignoreId=%u").c_str(), characterId, characterId);
			if (rst1.second && rst2.second) {
				buffer << u32(rst1.first + rst2.first);
				GameSession::Feedback(gsPtr, buffer, info.sn);
			} else {
				GameSession::FeedbackError(gsPtr, info.sn, DBPErrorInsertMysqlFailed);
			}
		} else {
			GameSession::FeedbackError(gsPtr, info.sn, DBPErrorConnectMysqlFailed);
		}
	};
	sDeferAsyncTaskMgr.AddTask(CreateAsyncTask(DeleteAllSocialData));
	return SessionHandleCapture;
}

int GameSessionHandler::HandleNewSocialFriend(GameSession *pSession, INetPacket &pck, const RPCActor::RequestMetaInfo &info)
{
	auto NewSocialFriend = [GSRPCAsyncTaskArgs]() {
		NetBuffer buffer;
		social_friend instInfo;
		LoadFromINetStream(instInfo, *pckPtr);
		auto connPtr = sMysqlDatabasePool.GetCharDB()->GetConnAutoPtr();
		if (connPtr) {
			auto sqlStr = CreateSQL4InsertEntity(instInfo);
			auto rst = connPtr->Execute(sqlStr.c_str());
			if (rst.second) {
				GameSession::Feedback(gsPtr, buffer, info.sn);
			} else {
				GameSession::FeedbackError(gsPtr, info.sn, DBPErrorInsertMysqlFailed);
			}
		} else {
			GameSession::FeedbackError(gsPtr, info.sn, DBPErrorConnectMysqlFailed);
		}
	};
	sAsyncTaskMgr.AddTask(CreateAsyncTask(NewSocialFriend));
	return SessionHandleCapture;
}

int GameSessionHandler::HandleDeleteSocialFriend(GameSession *pSession, INetPacket &pck, const RPCActor::RequestMetaInfo &info)
{
	auto DeleteSocialFriend = [GSRPCAsyncTaskArgs]() {
		NetBuffer buffer;
		uint32 characterId, friendId;
		(*pckPtr) >> characterId >> friendId;
		auto connPtr = sMysqlDatabasePool.GetCharDB()->GetConnAutoPtr();
		if (connPtr) {
			auto rst = connPtr->ExecuteFormat(CreateSQL4DeleteEntity<social_friend>
				("characterId=%u AND friendId=%u").c_str(), characterId, friendId);
			if (rst.second) {
				buffer << (u32)rst.first;
				GameSession::Feedback(gsPtr, buffer, info.sn);
			} else {
				GameSession::FeedbackError(gsPtr, info.sn, DBPErrorUpdateMysqlFailed);
			}
		} else {
			GameSession::FeedbackError(gsPtr, info.sn, DBPErrorConnectMysqlFailed);
		}
	};
	sAsyncTaskMgr.AddTask(CreateAsyncTask(DeleteSocialFriend));
	return SessionHandleCapture;
}

int GameSessionHandler::HandleNewSocialIgnore(GameSession *pSession, INetPacket &pck, const RPCActor::RequestMetaInfo &info)
{
	auto NewSocialIgnore = [GSRPCAsyncTaskArgs]() {
		NetBuffer buffer;
		social_ignore instInfo;
		LoadFromINetStream(instInfo, *pckPtr);
		auto connPtr = sMysqlDatabasePool.GetCharDB()->GetConnAutoPtr();
		if (connPtr) {
			auto sqlStr = CreateSQL4InsertEntity(instInfo);
			auto rst = connPtr->Execute(sqlStr.c_str());
			if (rst.second) {
				GameSession::Feedback(gsPtr, buffer, info.sn);
			} else {
				GameSession::FeedbackError(gsPtr, info.sn, DBPErrorInsertMysqlFailed);
			}
		} else {
			GameSession::FeedbackError(gsPtr, info.sn, DBPErrorConnectMysqlFailed);
		}
	};
	sAsyncTaskMgr.AddTask(CreateAsyncTask(NewSocialIgnore));
	return SessionHandleCapture;
}

int GameSessionHandler::HandleDeleteSocialIgnore(GameSession *pSession, INetPacket &pck, const RPCActor::RequestMetaInfo &info)
{
	auto DeleteSocialIgnore = [GSRPCAsyncTaskArgs]() {
		NetBuffer buffer;
		uint32 characterId, ignoreId;
		(*pckPtr) >> characterId >> ignoreId;
		auto connPtr = sMysqlDatabasePool.GetCharDB()->GetConnAutoPtr();
		if (connPtr) {
			auto rst = connPtr->ExecuteFormat(CreateSQL4DeleteEntity<social_ignore>
				("characterId=%u AND ignoreId=%u").c_str(), characterId, ignoreId);
			if (rst.second) {
				buffer << (u32)rst.first;
				GameSession::Feedback(gsPtr, buffer, info.sn);
			} else {
				GameSession::FeedbackError(gsPtr, info.sn, DBPErrorUpdateMysqlFailed);
			}
		} else {
			GameSession::FeedbackError(gsPtr, info.sn, DBPErrorConnectMysqlFailed);
		}
	};
	sAsyncTaskMgr.AddTask(CreateAsyncTask(DeleteSocialIgnore));
	return SessionHandleCapture;
}
